package de.wbh.gwt.form.layouter.shared.activity;

import java.util.List;

import com.allen_sauer.gwt.dnd.client.drop.CustomDropController;
import com.google.gwt.activity.shared.AbstractActivity;
import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.Scheduler;
import com.google.gwt.event.shared.EventBus;
import com.google.gwt.inject.client.AsyncProvider;
import com.google.gwt.user.client.Command;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.AcceptsOneWidget;
import com.google.inject.assistedinject.Assisted;
import com.google.inject.assistedinject.AssistedInject;

import de.wbh.gwt.form.layouter.gwt.rpc.EdgeDetectionServiceAsync;
import de.wbh.gwt.form.layouter.gwt.rpc.PcfService.PositionedField;
import de.wbh.gwt.form.layouter.gwt.rpc.PcfServiceAsync;
import de.wbh.gwt.form.layouter.gwt.ui.view.widget.Field;
import de.wbh.gwt.form.layouter.shared.Box;
import de.wbh.gwt.form.layouter.shared.event.DragControllerAddedEvent;
import de.wbh.gwt.form.layouter.shared.event.DropControllerAddedEvent;

public class EditPositionsActivity extends AbstractActivity implements EditPositionsView.Presenter, FieldRemovedEvent.Handler {

	private final AsyncProvider<EditPositionsView> viewProvider;

	private EditPositionsView view;

	private EventBus eventBus;

	private final String pdfName;

	private final EdgeDetectionServiceAsync edgeDetectionService;

	private final PcfServiceAsync pcfService;

	private final String confName;

	@AssistedInject
	public EditPositionsActivity(AsyncProvider<EditPositionsView> viewProvider, EdgeDetectionServiceAsync edgeDetectionService, PcfServiceAsync pcfService, @Assisted String pdfName,
			@Assisted String confName) {
		this.viewProvider = viewProvider;
		this.pdfName = pdfName;
		this.edgeDetectionService = edgeDetectionService;
		this.pcfService = pcfService;
		this.confName = confName;
	}

	@Override
	public void dropControllerAdded(final CustomDropController dropController) {
		Scheduler.get().scheduleDeferred(new Command() {

			@Override
			public void execute() {
				EditPositionsActivity.this.eventBus.fireEvent(new DropControllerAddedEvent(dropController));
			}
		});
	}

	@Override
	public void fieldsCreated(List<Field> fields) {
		this.eventBus.fireEvent(new FieldsCreatedEvent(fields));
	}

	@Override
	public void onFieldRemoved() {
		this.pcfService.updatePcf(this.confName, this.view.getPositionedFields(), new AsyncCallback<Void>() {
			@Override
			public void onFailure(Throwable caught) {
			}

			@Override
			public void onSuccess(Void result) {
			}
		});
	}

	@Override
	public void start(final AcceptsOneWidget panel, EventBus eventBus) {
		this.eventBus = eventBus;
		eventBus.addHandler(FieldRemovedEvent.getType(), this);
		eventBus.addHandler(DragControllerAddedEvent.getType(), new DragControllerAddedEvent.Handler() {

			@Override
			public void onDragControllerAdded(DragControllerAddedEvent event) {
				if (EditPositionsActivity.this.view != null) {
					EditPositionsActivity.this.view.dragControllerAdded(event.getDragController());
				}
			}
		});
		this.viewProvider.get(new AsyncCallback<EditPositionsView>() {

			@Override
			public void onFailure(Throwable caught) {
				caught.printStackTrace();
			}

			@Override
			public void onSuccess(EditPositionsView result) {
				EditPositionsActivity.this.view = result;
				EditPositionsActivity.this.view.showImage(GWT.getModuleBaseURL() + "image/" + EditPositionsActivity.this.pdfName);
				EditPositionsActivity.this.view.setPresenter(EditPositionsActivity.this);
				panel.setWidget(EditPositionsActivity.this.view);

				EditPositionsActivity.this.edgeDetectionService.getEdges(EditPositionsActivity.this.pdfName, new AsyncCallback<List<Box>>() {
					@Override
					public void onFailure(Throwable caught) {
						caught.printStackTrace();
					}

					@Override
					public void onSuccess(List<Box> result) {
						System.out.println(result);

						EditPositionsActivity.this.view.showBoxes(result);
					}
				});

				EditPositionsActivity.this.pcfService.getPositionedFields(EditPositionsActivity.this.confName, new AsyncCallback<List<PositionedField>>() {
					@Override
					public void onFailure(Throwable caught) {
					}

					@Override
					public void onSuccess(List<PositionedField> result) {
						EditPositionsActivity.this.view.addFields(result);
					}
				});
			}
		});
	}

	@Override
	public void updatePositions(List<PositionedField> positionedFields) {
		System.out.println("update positions for " + positionedFields.size() + " fields");
		this.pcfService.updatePcf(this.confName, positionedFields, new AsyncCallback<Void>() {
			@Override
			public void onFailure(Throwable caught) {
				caught.printStackTrace();
			}

			@Override
			public void onSuccess(Void result) {
				System.out.println("JUHUUUUUU");
			}
		});
	}
}
